Jakikolwiek kod mogę wrzucić, tyle że ten testowy akurat działa bardzo wydajnie.
rollback;
\pset pager off
\timing off
SET statement_timeout = 0;
SET client_encoding = 'UTF8';
SET standard_conforming_strings = on;
SET check_function_bodies = false;
SET client_min_messages = warning;
\c postgres;
set role postgres;
DROP DATABASE IF EXISTS testabc;
DROP TABLESPACE IF EXISTS testabcspace;
DROP ROLE IF EXISTS testabc;
CREATE ROLE testabc PASSWORD 'testabc' NOSUPERUSER NOCREATEDB NOCREATEROLE INHERIT LOGIN;
CREATE DATABASE testabc OWNER testabc ENCODING 'UTF-8';
\c testabc;
create or replace function random_string(length integer) returns text as
$$
declare
chars text[] := '{a,b,c,d,e,f,g,h,i,j,k,l,m,n,o,p,r,s,t,u,v,w,x,y,z,0,1,2,3,4,5,6,7,8,9,A,B,C,D,E,F,G,H,I,J,K,L,M,N,O,P,R,S,T,U,V,W,X,Y,Z}';
result text := '';
i integer := 0;
begin
for i in 1..length loop
result := result || chars[1+random()*(array_length(chars, 1)-1)];
end loop;
return result;
end;
$$ language plpgsql;
CREATE SEQUENCE seq_testabc START WITH 1 INCREMENT BY 1 NO MINVALUE NO MAXVALUE CACHE 100;
CREATE TABLE testabc (
id bigint DEFAULT nextval('seq_testabc') NOT NULL,
val int NOT NULL, -- pole pomocne w testach, tylko do sum kontrolnych
f1 int NOT NULL, -- pole na które nakładane są warunki, normalnie jest to id obce z innej małej tabeli rzędu 12 rekordów
f2 int NOT NULL, -- pole na które nakładane są warunki, normalnie jest to id obce z innej małej tabeli rzędu 12 rekordów
f3 int NOT NULL, -- pole na które nakładane są warunki, normalnie jest to id obce z innej małej tabeli rzędu 1000 rekordów
st1 character varying(20) NOT NULL, -- pole które zawiera dane tylko do wyświetlania, nigdy nie nakładamy warunków na to pole
st2 character varying(20) NOT NULL, -- pole które zawiera dane tylko do wyświetlania, nigdy nie nakładamy warunków na to pole
st3 character varying(20) NOT NULL -- pole które zawiera dane tylko do wyświetlania, nigdy nie nakładamy warunków na to pole
);
create or replace function mk_data(length integer) returns void as
$$
declare
i integer;
vval bigint;
vf1 integer;
vf2 integer;
vf3 integer;
vst1 text;
vst2 text;
vst3 text;
begin
for i in 1..length loop
vval = floor( random() * 1000000000 );
vf1 = floor( random() * 12 + 1 );
vf2 = floor( random() * 12 + 1 );
vf3 = floor( random() * 1000 + 1 );
vst1 = random_string( 20 );
vst2 = random_string( 20 );
vst3 = random_string( 20 );
execute 'insert into testabc (val,f1,f2,f3,st1,st2,st3) values($1, $2, $3, $4, $5, $6, $7)' using vval, vf1, vf2, vf3, vst1, vst2, vst3;
end loop;
end;
$$ language plpgsql;
begin;
\timing on
select mk_data(10000000);
\timing off
commit;
SELECT nspname || '.' || relname AS "relation",
pg_size_pretty(pg_total_relation_size(C.oid)) AS "total_size"
FROM pg_class C
LEFT JOIN pg_namespace N ON (N.oid = C.relnamespace)
WHERE nspname NOT IN ('pg_catalog', 'information_schema')
AND C.relkind <> 'i'
AND nspname !~ '^pg_toast'
ORDER BY pg_total_relation_size(C.oid) DESC;
--czy wszystko może zmieścić się w ram? ( u mnie 4000MB )
show shared_buffers ;
\timing on
-- jaki jest narzut czasowy na najprostsze zapytanie? Nie traci czasu na jakieś logi?
select id from testabc limit 1; -- tutaj powinien się połączyć ( u mnie czasy od 0.2ms do 0.5ms )
--test bez indeksów
select * from testabc where f1=3 and f2=5 and f3 in ( 1,5,17,20,33,81,121,301,345,400,451,501,502,503,800,922,981) and id <= 1321875 order by id desc limit 30;
explain (analyze, buffers) select * from testabc where f1=3 and f2=5 and f3 in ( 1,5,17,20,33,81,121,301,345,400,451,501,502,503,800,922,981) and id <= 1321875 order by id desc limit 30;
--index na samo id
create index idx1 on testabc (id);
select * from testabc where f1=3 and f2=5 and f3 in ( 1,5,17,20,33,81,121,301,345,400,451,501,502,503,800,922,981) and id <= 2321875 order by id desc limit 30;
explain (analyze, buffers) select * from testabc where f1=3 and f2=5 and f3 in ( 1,5,17,20,33,81,121,301,345,400,451,501,502,503,800,922,981) and id <= 2321875 order by id desc limit 30;
--index na wszystkie pola, id na końcu
create index idx2 on testabc (f1,f2,f3,id);
select * from testabc where f1=3 and f2=5 and f3 in ( 1,5,17,20,33,81,121,301,345,400,451,501,502,503,800,922,981) and id <= 3321875 order by id desc limit 30;
explain (analyze, buffers) select * from testabc where f1=3 and f2=5 and f3 in ( 1,5,17,20,33,81,121,301,345,400,451,501,502,503,800,922,981) and id <= 3321875 order by id desc limit 30;
Wg mnie jednak jesteś sporym ignorantem. Twoim zdaniem ilość danych i schemat bazy nie powinny mieć wpływu, naszym zdaniem powinny.
Tak, mogą mieć wpływ, ale zwróć uwagę, o jakie 'inne dane' chodzi. Inne dane to np. dodatkowe kolumny w tabeli na które nie ma założonego żadnego warunku w zapytaniu. Albo inne dane w tabeli która nie bierze udziału w zapytaniu. Albo inne wartości danych, bo dane pochodzą z funkcji rand. Jeśli ktoś nie zna wpływu takich szczegółów, to po prostu nie jest specjalistą, a ignorancja to raczej oznacza kompletny brak wiedzy z całej dziedziny.